package com.github.natholdallas.controller.user

import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.github.natholdallas.common.*
import com.github.natholdallas.controller.PageIn
import com.github.natholdallas.controller.TinyUserSerializer
import com.github.natholdallas.database.*
import com.github.natholdallas.declaration.Attr
import com.github.natholdallas.declaration.Body
import com.github.natholdallas.declaration.Path
import org.springframework.data.domain.Page
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PutMapping

@UViews("/user")
class UserCtl(private val repo: Users) {

    @[GetMapping]
    fun retrieve(): User {
        return repo.byId(LOGINID)
    }

    @[PutMapping]
    fun update(@Body data: UserIn) {
        repo.byIdThenUpdate(LOGINID, data)
    }

}


@UViews("/copilot")
class CopilotCtl(private val repo: Users) {

    @[GetMapping("/trendings/{v}")]
    fun trendings(@Path v: String): List<User> {
        return repo.allByTag(v)
    }

    @[GetMapping("/search/{v}")]
    fun search(@Path v: String): List<User> {
        return repo.allByTagOrName(v)
    }

    @[GetMapping("/tinylist") JsonSerialize(using = TinyUserSerializer::class)]
    fun tinylist(): List<User> {
        return repo.all(Role.COPILOT)
    }

    @[GetMapping]
    fun list(@Attr page: PageIn): Page<User> {
        return repo.all(Role.COPILOT, page)
    }

    @[GetMapping("/{id}")]
    fun retrieve(@Path id: Long): User {
        return repo.byId(id)
    }

}


@UViews("/comment")
class CommentCtl(private val repo: Comments) {

    @[GetMapping("/{copilot}")]
    fun list(@Path copilot: Long): List<CommentTable> {
        return repo.allByCopilot(copilot)
    }


    @[PostMapping]
    fun create(@Body data: CommentIn) {
        repo.save(data)
    }

}


@UViews("/topup")
class TopupCtl(private val repo: Topups) {

    @[GetMapping]
    fun list(@Attr page: PageIn): Page<TopupTable> {
        return repo.allByUser(LOGINID, page)
    }

    @[GetMapping("/{id}")]
    fun retrieve(@Path id: Long): TopupTable {
        return repo.byId(id)
    }

    @[PostMapping]
    fun create(@Body data: TopupIn) {
        repo.save(data)
        saveLog("[$USERNAME] 新增转账 $data")
    }

}


@UViews("/order")
class OrderCtl(private val repo: Orders) {

    @[GetMapping]
    fun list(@Attr page: PageIn): Page<OrderTable> {
        return repo.allByUser(LOGINID, page)
    }

    @[GetMapping("/{id}")]
    fun retrieve(@Path id: Long): OrderTable {
        return repo.byId(id)
    }

    @[PostMapping]
    fun create(@Body data: OrderIn) {
        repo.save(data)
        saveLog("[$USERNAME] 新增订单 $data")
    }

}


@UViews("/star")
class StarCtl(private val repo: Stars) {

    @[GetMapping]
    fun list(@Attr page: PageIn): Page<User> {
        return repo.allByUser(LOGINID, page).map { it.copilot }
    }

    @[PostMapping]
    fun create(@Body data: StarIn) {
        repo.save(data)
    }

}
